function hashTable() {
  this.storage = []
  this.count = 0
  this.limit = 7 // storage的长度（设置为质数）

  // 用于计算loadfactor(loadfactor>0.75的时候，
  // 需要对数组进行扩容,loadfactor<0.25缩小数组

  // 哈希函数
  hashTable.prototype.hashFunc = function(str, size) {
    // 1.定义hashCode变量
    let hashCode = 0

    // 2.霍纳算法，来计算hashCode的值
    // 获取Unicode编码
    str.split("").forEach((char, index) => {
      hashCode = 37 * hashCode + str.charCodeAt(index)
    })

    // 3.取余操作
    let index = hashCode % size

    return index
  }

  // 1.插入和修改方法
  hashTable.prototype.put = function(key, value) {
    // 插入的数据为[key,value]形式，若key存在，则修改。不存在，则创建(key是索引的一种转换，value是要保存的值)

    // 1.根据key得到索引
    let index = this.hashFunc(key, this.limit)
      // 2.判断索引处bucket是否存在（不存在新建，并放置在该索引处）
    let bucket = this.storage[index]
    if (!bucket) {
      this.storage[index] = new Array([key, value])
      this.count++
        this.judgeExpansion()
      return this
    }
    // 3.判断是修改还是新增操作（查找得到key就修改，找不到就新增）
    // >3.1根据key查找元素(找到就修改，找不到就新建)
    for (let item of bucket) {
      if (key === item[0]) return item[1] = value
    }
    bucket.push([key, value])
    this.count++
      this.judgeExpansion()
    return this
  }

  // 2.获取方法
  hashTable.prototype.get = function(key) {
    // 根据值获取索引
    let index = this.hashFunc(key, this.limit)

    //该值不存在
    let bucket = this.storage[index]
    if (!bucket) return null

    for (let item of bucket) {
      if (item[0] === key) return item[1]
    }

  }

  // 3.删除操作
  hashTable.prototype.remove = function(key) {
    // 根据值获取索引
    let index = this.hashFunc(key, this.limit)

    // 值不存在
    let bucket = this.storage[index]
    if (!bucket) return null

    for (let [index, item] of bucket.entries()) {
      if (item[0] === key) {
        this.count--
          this.judgeExpansion()
        return bucket.splice(index, 1)
      }
    }
    return null
  }

  //4.判断为空
  hashTable.prototype.isEmpty = function() {
    return this.count === 0
  }

  // 5.获取哈希表中元素的个数
  hashTable.prototype.size = function() {
    return this.count
  }

  // 6.哈希表扩容
  hashTable.prototype.resize = function(newLimit) {
    let oldStorage = this.storage

    this.storage = []
    this.limit = newLimit
    this.count = 0

    // 遍历每个值
    oldStorage.forEach(bucket => {
      if (bucket) {
        bucket.forEach(item => {
          this.put(...item)
          this.count++
        })
      }
    })
  }

  // 7.判断扩容发生条件
  hashTable.prototype.judgeExpansion = function() {
    if (this.count > 0.75 * this.limit) {
      this.limit *= 2
      while (!this.isPrime(this.limit)) this.limit++
    } else if (this.count < 0.25 * this.limit) {
      this.limit = Math.floor(this.limit / 2)
      while (!this.isPrime(this.limit)) this.limit++
    }
  }

  // 8.判断是否为质数
  hashTable.prototype.isPrime = function(num) {
    for (let i = 2; i <= Math.sqrt(num); i++) {
      if (num % i === 0) {
        return false
      }
    }
    return true
  }

}

module.exports = hashTable

// let h = new hashTable()
// for (let i = 0; i < 100; i++) {
//   h.put('h' + i, i)
//   console.log(h.isPrime(h.limit));
// }
function getObj() {
  return {
    uname: 'cuifan',
    age: 20
  }
}

console.log(getObj() == getObj());